﻿using System;
using System.Collections;
using System.Data;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using CObject;
using Objects.CMT;
using Objects.Security;

/// <summary>
/// Code behind class for Group Management Page
/// </summary>
public partial class GroupManagement : Objects.cSecurePage
{
    #region Properties

    /// <summary>
    /// Gets or sets the Group ID
    /// </summary>
    public int GroupID
    {
        get
        {
            if (ViewState["GroupID"] == null)
                return 0;
            else
                return int.Parse(ViewState["GroupID"].ToString());

        }
        set { ViewState["GroupID"] = value; }
    }

    /// <summary>
    /// Gets or sets the Rights to be removed from the
    /// database
    /// </summary>
    public ArrayList RightsID
    {
        get
        {
            if (ViewState["RightsID"] == null)
                return null;
            else
                return ViewState["RightsID"] as ArrayList;

        }
        set { ViewState["RightsID"] = value; }
    }
    #endregion

    #region Events

    /// <summary>
    /// Page load event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.Page.IsPostBack)
        {
            this.BindGroups();
        }
    }

    /// <summary>
    /// Event for saving new Group details
    /// </summary>
    /// <param name="sender">The sending object</param>
    /// <param name="e">The event arguments.</param>
    protected void btnSave_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            Group group = new Group();
            if (GroupID > 0)
                group.GroupID = GroupID;
            group.ContactLevel = string.IsNullOrEmpty(txtContactLevel.Text) ? 0 : Convert.ToInt32(txtContactLevel.Text);
            group.Description = txtDescription.Text.Trim();
            group.Name = txtName.Text.Trim();
            if (this.SaveGroup(group))
            {
                this.BindGroups();
                ScriptManager.RegisterStartupScript(this, this.GetType(), "hideaddnew", "HideAddNew()", true);

                // Clear the values
                this.ClearControls();
            }
            else
            {
                lblErrorAddNew.Text = "Group Name is not unique";
            }
        }
    }

    /// <summary>
    /// Add users to the group
    /// </summary>
    /// <param name="sender">The sending object</param>
    /// <param name="e">The event arguments</param>
    protected void btnAddUsers_Click(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(empLookUp.value))
        {
            lblUserList.Text = "Invalid entry.";
        }
        else if (lstAssignedUsers.Items.FindByValue(empLookUp.value) == null)
        {
            lstAssignedUsers.Items.Add(new ListItem(empLookUp.Text, empLookUp.value));
            empLookUp.Text = string.Empty;
        }
        else
        {
            lblUserList.Text = "User already added.";
        }
    }

    /// <summary>
    /// Removes users from the group
    /// </summary>
    /// <param name="sender">The sending object</param>
    /// <param name="e">Event Arguments</param>
    protected void btnRemoveUsers_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < lstAssignedUsers.Items.Count; i++)
        {
            if (lstAssignedUsers.Items[i].Selected)
            {
                if (lstAssignedUsers.Items[i].Value.Contains("|"))
                {
                    RightsID = RightsID ?? new ArrayList();
                    RightsID.Add(lstAssignedUsers.Items[i].Value.Split('|')[0]);
                }
                lstAssignedUsers.Items.RemoveAt(i);
            }
        }
        lblUserList.Text = string.Empty;
    }

    #endregion

    #region Grid View Events

    /// <summary>
    /// Grid view event for deleting a row
    /// </summary>
    /// <param name="sender">The sending object</param>
    /// <param name="e">Delete event argument</param>
    protected void gvGroupList_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        Group group = new Group() { GroupID = Convert.ToInt32(gvGroupList.DataKeys[e.RowIndex].Value.ToString()) };
        group.Delete();

        // Delete associated user rights
        SecurityUserRight userRight = null;
        foreach (DataRow dr in group.UserRights.Rows)
        {
            userRight = new SecurityUserRight(int.Parse(dr["RightsID"].ToString()));
            userRight.Delete();
        }

        this.BindGroups();
    }

    /// <summary>
    /// Grid view row command event for editing
    /// </summary>
    /// <param name="sender">The sending object</param>
    /// <param name="e">Event arguments</param>
    protected void gvGroupList_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "EditGroup")
        {
            ScriptManager.RegisterStartupScript(this, this.GetType(), "showaddnew", "ShowAddNew();", true);
            GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
            txtName.Text = row.Cells[0].Text;
            txtDescription.Text = row.Cells[1].Text.Replace("&nbsp;", string.Empty);
            txtContactLevel.Text = row.Cells[2].Text;
            GroupID = Convert.ToInt32(this.gvGroupList.DataKeys[row.RowIndex].Value.ToString());

            // Bind UserRights
            Group group = new Group() { GroupID = GroupID };
            this.BindUsers(group);
        }
    }

    /// <summary>
    /// Add new and cancel event
    /// </summary>
    /// <param name="sender">The sending object Add New/Cancel Button</param>
    /// <param name="e">The Click Event Handler</param>
    protected void btnClear_Click(object sender, EventArgs e)
    {
        this.ClearControls();
    }
    #endregion

    #region Private Functions

    /// <summary>
    /// Function to get the list
    /// of existing Groups/groups.
    /// </summary>
    /// <returns>Datatable containing the list of Groups.</returns>
    private DataTable GetGroups()
    {
        CCollection groupCollectionList = new CCollection(new Group(), true);
        return groupCollectionList.DataTable;
    }

    /// <summary>
    /// Function to bind list of Groups to 
    /// the grid view.
    /// </summary>
    private void BindGroups()
    {
        this.gvGroupList.DataSource = this.GetGroups();
        this.gvGroupList.DataBind();
    }

    /// <summary>
    /// Function to save Group details.
    /// </summary>
    /// <param name="group">The group details to be saved to database</param>
    /// <returns>Whether the save operation was success</returns>
    private bool SaveGroup(Group group)
    {
        // Check whther the group name is unique
        DataTable dtGroupList = this.GetGroups();
        string selectExpression = string.Empty;
        if (group.GroupID == 0)
        {
            selectExpression = "Name = '" + group.Name + "'";
        }
        else
        {
            selectExpression = "GroupID <> '" + group.GroupID + "' AND Name = '" + group.Name + "'";
        }

        DataRow[] modelDetails = dtGroupList.Select(selectExpression);
        if (modelDetails.Count() > 0)
        {
            txtName.Focus();
            return false;
        }
        else
        {
            group.Save();
            this.SaveUserRight(group);
            return true;
        }
    }

    /// <summary>
    /// Function to associate the user to a group
    /// </summary>
    /// <param name="group">The group details.</param>
    private void SaveUserRight(Group group)
    {
        SecurityUserRight securityUserRight = null;
        for (int i = 0; i < lstAssignedUsers.Items.Count; i++)
        {           
            if (lstAssignedUsers.Items[i].Value.Split('|').Count() == 1)
            {
                securityUserRight = new SecurityUserRight() { GroupID = group.GroupID, Groups = group.Name, GUI = lstAssignedUsers.Items[i].Value, Exception = false };
                securityUserRight.Save();
            }
        }

        // Delete the rights removed
        SecurityUserRight userRight = null;
        if (RightsID != null)
        {
            foreach (string rightID in RightsID)
            {
                userRight = new SecurityUserRight(int.Parse(rightID));
                userRight.Delete();
            }
        }
    }

    /// <summary>
    /// Function to bind associated users
    /// to the selected group.
    /// </summary>
    /// <param name="group">The group object</param>
    private void BindUsers(Group group)
    {
        lstAssignedUsers.Items.Clear();
        if (group.UserRights.Rows.Count > 0)
        {
            foreach (DataRow dr in group.UserRights.Rows)
            {
                lstAssignedUsers.Items.Add(new ListItem() { Value = dr["RightsID"].ToString() + "|" + dr["GUI"].ToString(), Text = dr["Name"].ToString() });
            }
        }
    }

    /// <summary>
    /// Function to clear the 
    /// controls value
    /// </summary>
    private void ClearControls()
    {
        txtContactLevel.Text = string.Empty;
        txtDescription.Text = string.Empty;
        txtName.Text = string.Empty;
        lblErrorAddNew.Text = string.Empty;
        RightsID = null;
        GroupID = 0;
        lstAssignedUsers.Items.Clear();
        lblUserList.Text = string.Empty;
        empLookUp.Text = string.Empty;
    }

    #endregion

}